package controllers

import (
	"classOne/models"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"math"
	"path"
	"strconv"
	"time"
)

type ArticleController struct {
	beego.Controller
}

//处理下拉框改变引发的请求
func (this *ArticleController) HandleSelect() {
	//1.接收参数
	typeName := this.GetString("select")
	//2.处理数据
	if typeName == "" {
		beego.Info("下拉框传递数据失败")
		return
	}
	//3.查询数据
	o := orm.NewOrm()
	var articles []models.Article
	o.QueryTable("Article").RelatedSel("ArticleType").Filter("ArticleType__TypeName", typeName).All(&articles)
	beego.Info(articles)
}

//展示文章列表页
func (this *ArticleController) ShowArticleList() {

	userName := this.GetSession("userName")
	if userName == nil {
		this.Redirect("/", 302) //如果没有session，回到登录界面
		return
	}

	//1.查询
	o := orm.NewOrm()
	qs := o.QueryTable("Article")
	var articles []models.Article
	//qs.All(&articles) // select * from Article
	count, err := qs.RelatedSel("ArticleType").Count() //返回数据条目数量
	//获取总页数
	pageSize := 2
	pageIndex := 1
	pageIndex1, pageIndexErr := this.GetInt("pageIndex")
	if pageIndexErr == nil {
		pageIndex = pageIndex1
	}
	start := pageSize * (pageIndex - 1)
	qs.Limit(pageSize, start).RelatedSel("ArticleType").All(&articles) //1.pagesize 一页显示多少  2.start起始位置

	pageCount := math.Ceil(float64(count) / float64(pageSize))
	if err != nil {
		beego.Info("查询错误")
		return
	}
	beego.Info("count = ", count)
	//beego.Info(articles[0])

	var artiTypes []models.ArticleType
	//获取类型数据
	o.QueryTable("ArticleType").All(&artiTypes)

	//2.把数据传递给数据显示
	this.Data["count"] = count
	this.Data["types"] = artiTypes
	this.Data["articles"] = articles
	this.Data["pageCount"] = pageCount

	this.Data["pageIndex"] = pageIndex
	if pageIndex == 1 {
		FirstPage := true
		this.Data["FirstPage"] = FirstPage
	}

	this.TplName = "index.html"
}

func (this *ArticleController) ShowAddArticle() {
	//读取数据类型
	o := orm.NewOrm()
	var artiTypes []models.ArticleType
	//查询
	o.QueryTable("ArticleType").All(&artiTypes)

	this.Data["artiTypes"] = artiTypes

	this.TplName = "add.html"
}

func (this *ArticleController) HandleAddArtcile() {
	artiName := this.GetString("articleName")
	artiContent := this.GetString("content")
	beego.Info(artiName, artiContent)

	file, fileHeader, error := this.GetFile("uploadname")
	//1.判断文件格式
	ext := path.Ext(fileHeader.Filename)
	beego.Info(ext)
	if ext != ".jpg" && ext != ".png" && ext != "jpeg" {
		beego.Info("上传文件格式不正确")
		return
	}
	//2.判断文件大小
	if fileHeader.Size > 5000000 {
		beego.Info("文件太大，不允许上传")
		return
	}
	//3.不能重名
	newFileName := time.Now().Format("2006-01-02 15:04:05")
	err := this.SaveToFile("uploadname", "static/img/"+newFileName+ext)

	defer file.Close()

	if error != nil {
		beego.Info("文件上传错误", error)
		return
	}
	if err != nil {
		beego.Info("文件存储错误", err)
		return
	}
	beego.Info(fileHeader.Filename)

	//插入数据
	o := orm.NewOrm()
	article := models.Article{}
	article.Title = artiName
	article.Content = artiContent
	article.Img = "static/img/" + newFileName + ext

	//获取到下拉框传递过来的类型数据
	typeName := this.GetString("select")
	if typeName == "" {
		beego.Info("下拉框数据错误")
		return
	}
	//获取type对象
	var artiType models.ArticleType
	artiType.TypeName = typeName
	err = o.Read(&artiType, "TypeName")
	if err != nil {
		beego.Info("获取类型错误", err)
		return
	}
	article.ArticleType = &artiType

	_, err = o.Insert(&article)
	if err != nil {
		beego.Info("插入数据失败")
		return
	}
	//4.返回视图

	this.Redirect("/Article/ShowArticle", 302)
}

func (this *ArticleController) ShowContent() {
	id := this.GetString("id")
	//获取orm对象
	o := orm.NewOrm()
	//获取查询对象
	id2, _ := strconv.Atoi(id)
	article := models.Article{Id2: id2}
	//3查询
	err := o.Read(&article)
	if err != nil {
		beego.Info("查询数据为空")
		return
	}
	article.Count += 1
	//多对多插入读者

	//1.获取操作对象
	//  artile :=models.Article{Id2:id2}
	//2.获取多对多操作对象
	m2m := o.QueryM2M(&article, "Users")
	//3.获取插入对象
	userName := this.GetSession("userName")
	user := models.User{}
	user.UserName = userName.(string)
	o.Read(&user, "UserName")

	//4.多对多插入
	_, err = m2m.Add(&user)
	if err != nil {
		beego.Info("插入失败")
		return
	}
	o.Update(&article) //没有指定更新哪一列，他会自己查
	//多对多查询

	// o.LoadRelated(&article,"Users")//问题：会显示重复的数据
	//去重处理
	var users []models.User
	o.QueryTable("User").Filter("Articles__Article__Id2", id2).Distinct().All(&users)

	beego.Info(article)

	this.Data["users"] = users

	//3.传递数据给视图
	this.Data["article"] = article
	this.TplName = "content.html"
}

//1.URL传值

//删除文章
func (this *ArticleController) HandleDelete() {
	id := this.GetString("id")
	o := orm.NewOrm()
	id2, _ := strconv.Atoi(id)
	article := models.Article{Id2: id2}
	_, err := o.Delete(&article)
	if err != nil {
		beego.Info("数据删除失败", err)
		return
	}
	this.Redirect("/Article/ShowArticle", 302)

}

//显示更新页面
func (this *ArticleController) ShowUpdate() {
	//获取数据
	id := this.GetString("id")
	if id == "" {
		beego.Info("连接错误")
		return
	}
	//条件查询
	o := orm.NewOrm()
	id2, _ := strconv.Atoi(id)
	article := models.Article{Id2: id2}
	err := o.Read(&article)
	if err != nil {
		beego.Info("查询错误")
		return
	}
	//把数据传递给视图
	this.Data["article"] = article
	this.TplName = "update.html"
}
func (this *ArticleController) HandleUpdate() {
	name := this.GetString("articleName")
	content := this.GetString("content")
	id, _ := this.GetInt("id")

	//问题一 id是不是没有传过来
	if name == "" || content == "" {
		beego.Info("更新数据失败")
		return
	}
	f, h, err := this.GetFile("uploadname")
	if err != nil {
		beego.Info("上传文件失败")
		return
	}
	defer f.Close()
	//1.判断大小
	if h.Size > 5000000 {
		beego.Info("图片太大")
		return
	}
	//判断类型
	ext := path.Ext(h.Filename)
	if ext != ".jpg" && ext != ".png" && ext != ".jpeg" {
		beego.Info("上传文件类型错误")
		return
	}
	//防止文件名重复
	fileName := time.Now().Format("2006-01-02 15:04:05")
	this.SaveToFile("uploadname", "static/img"+fileName+ext)

	//更新操作
	o := orm.NewOrm()
	article := models.Article{Id2: id}
	//读取操作
	err = o.Read(&article)
	if err != nil {
		beego.Info("要更新的文章不存在")
		return
	}
	//更新
	article.Title = name
	article.Content = content
	article.Img = "static/img" + fileName + ext
	_, err = o.Update(&article)
	if err != nil {
		beego.Info("更新失败")
		return
	}
	this.Redirect("/Article/ShowArticle", 302)
}

func (this *ArticleController) ShowAddType() {
	//1.读取类型表，显示数据
	o := orm.NewOrm()
	var artiTypes []models.ArticleType
	//查询
	_, err := o.QueryTable("ArticleType").All(&artiTypes)
	if err != nil {
		beego.Info("查询类型错误")
	}
	this.Data["types"] = artiTypes
	this.TplName = "addType.html"
}

//处理添加类型业务
func (this *ArticleController) HandleAddType() {
	//1.获取数据
	typename := this.GetString("typeName")
	if typename == "" {
		beego.Info("数据不能为空")
		return
	}
	o := orm.NewOrm()
	articleType := models.ArticleType{TypeName: typename}
	_, err := o.Insert(&articleType)
	if err != nil {
		beego.Info("插入失败")
		return
	}
	//4.展示视图
	this.Redirect("/AddArticleType", 302)
}

func (this *ArticleController) Logout() {

	//1.删除登录状态
	this.DelSession("userName")
	//2.跳转登录页面
	this.Redirect("/", 302)
}
